In general, you should avoid relying on the values of system global variables whenever possible. However, you might occasionally need to access the value of one of these variables. Because the actual values associated with global variables in MPW's SysEqu.p interface file are memory locations, you can access the value of a low-memory variable simply by dereferencing a memory location.
Many system global variables are process-independent, but some are process-specific. The Operating System swaps the values of the process-specific variables as it switches processes. If you write interrupt code that reads low memory, that code could execute at a time when another process's system global variables are installed. Therefore, before reading low memory from interrupt code, you should call the Process Manager to ensure that your process is the current process. If it is not, you should not rely on the value of system global variables that could conceivably be process-specific.
No available documentation distinguishes process-specific from process-independent system global variables.
The routine defined in Listing 1 illustrates how you can read a system global variable, in this case the system global variable BufPtr , which gives the address of the highest byte of allocatable memory.
Listing 1 Reading the value of a system global variable
FUNCTION FindHighestByte: LongInt;
TYPE
LongPtr = ^LongInt;
BEGIN
FindHighestByte := LongPtr(BufPtr)^;
END;
In Pascal, the main technique for reading system global variables is to define a new data type that points to the variable type you want to read. In this example, the address is stored as a long integer. Thus, the memory location BufPtr is really a pointer to a long integer. Because of Pascal's strict typing rules, you must cast the low-memory address into a pointer to a long integer. Then, you can dereference the pointer and return the long integer itself as the function result.
You can use a similar technique to change the value of a system global variable. For example, suppose you are writing an extension that displays a window at startup time. To maintain compatibility with pre-Macintosh II systems, you need to clear the system global variable named DeskHook . This global variable holds a ProcPtr that references a procedure called by system software to paint the desktop. If the value of the pointer is NIL , the system software uses the standard desktop pattern. If you do not set DeskHook to NIL , the system software might attempt to use whatever random data it contains to call an updating procedure when you move or close your window. The procedure defined in Listing 2 sets DeskHook to NIL .
Listing 2 Changing the value of a system global variable
PROCEDURE ClearDeskHook;
TYPE
ProcPtrPtr = ^ProcPtr; {pointer to ProcPtr}
VAR
deskHookProc: ProcPtrPtr;
BEGIN
deskHookProc := ProcPtrPtr(DeskHook); {initialize variable}
deskHookProc^ := NIL; {clear DeskHook proc}
END;
You can use a similar technique to change the value of any other documented system global variable.